package com.engine4cloud.tdf.admin.controller;

import cn.hutool.core.lang.tree.Tree;
import com.engine4cloud.tdf.admin.api.dto.AreaDepartQueryDTO;
import com.engine4cloud.tdf.admin.api.entity.SysDept;
import com.engine4cloud.tdf.admin.api.vo.DeptExcelVO;
import com.engine4cloud.tdf.admin.api.vo.OrgTreeVO;
import com.engine4cloud.tdf.admin.service.SysDeptService;
import com.engine4cloud.tdf.common.core.util.R;
import com.engine4cloud.tdf.common.excel.annotation.RequestExcel;
import com.engine4cloud.tdf.common.excel.annotation.ResponseExcel;
import com.engine4cloud.tdf.common.log.annotation.SysLog;
import com.engine4cloud.tdf.common.security.annotation.Inner;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.AllArgsConstructor;
import org.springframework.http.HttpHeaders;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 部门管理 前端控制器
 * </p>
 *
 * @author tdf
 * @since 2018-01-20
 */
@RestController
@AllArgsConstructor
@RequestMapping("/dept")
@Tag(description = "dept", name = "部门管理模块")
@SecurityRequirement(name = HttpHeaders.AUTHORIZATION)
public class SysDeptController {

    private final SysDeptService sysDeptService;

    /**
     * 通过ID查询
     *
     * @param id ID
     * @return SysDept
     */
    @GetMapping("/{id}")
    public R<?> getById(@PathVariable Long id) {
        return R.ok(sysDeptService.getById(id));
    }

    /**
     * 查询全部部门
     */
    @Inner
    @GetMapping("/list")
    public R<?> list() {
        return R.ok(sysDeptService.list());
    }

    /**
     * 返回树形菜单集合
     *
     * @param deptName 部门名称
     * @return 树形菜单
     */
    @GetMapping(value = "/tree")
    public R<List<Tree<Long>>> getTree(String deptName, Long parentId) {
        return R.ok(sysDeptService.selectTree(deptName, parentId));
    }

    /**
     * 获取父部门
     *
     * @param deptId 部门id
     * @return 树形菜单
     */
    @Inner
    @GetMapping(value = "/parent/{deptId}")
    public R<SysDept> getParentBySonId(@PathVariable("deptId") Long deptId) {
        return R.ok(sysDeptService.getParentBySonId(deptId));
    }


    /**
     * 返回获取子孙id列表
     *
     * @param parentId 部门id
     * @return 树形菜单
     */
    @Inner
    @GetMapping(value = "/descendant")
    public R<List<Long>> descendant(@RequestParam("parentId") Long parentId) {
        return R.ok(sysDeptService.descendant(parentId));
    }

    /**
     * 添加
     *
     * @param sysDept 实体
     * @return success/false
     */
    @SysLog("添加部门")
    @PostMapping
    @PreAuthorize("@pms.hasPermission('sys_dept_add')")
    public R<Boolean> save(@Valid @RequestBody SysDept sysDept) {
        return R.ok(sysDeptService.save(sysDept));
    }

    /**
     * 删除
     *
     * @param id ID
     * @return success/false
     */
    @SysLog("删除部门")
    @DeleteMapping("/{id}")
    @PreAuthorize("@pms.hasPermission('sys_dept_del')")
    public R<Boolean> removeById(@PathVariable Long id) {
        return R.ok(sysDeptService.removeDeptById(id));
    }

    /**
     * 编辑
     *
     * @param sysDept 实体
     * @return success/false
     */
    @SysLog("编辑部门")
    @PutMapping
    @PreAuthorize("@pms.hasPermission('sys_dept_edit')")
    public R<Boolean> update(@Valid @RequestBody SysDept sysDept) {
        sysDept.setUpdateTime(LocalDateTime.now());
        return R.ok(sysDeptService.updateById(sysDept));
    }

    /**
     * 查收子级列表
     *
     * @return 返回子级
     */
    @GetMapping(value = "/getDescendantList/{deptId}")
    public R<List<SysDept>> getDescendantList(@PathVariable Long deptId) {
        return R.ok(sysDeptService.listDescendant(deptId));
    }

    @GetMapping(value = "/leader/{deptId}")
    public R<List<Long>> getAllDeptLeader(@PathVariable Long deptId) {
        return R.ok(sysDeptService.listDeptLeader(deptId));
    }

    /**
     * 内部调用，不需要权限
     *
     * @param deptId 部门id
     * @return R<SysDept>
     */
    @Inner
    @GetMapping(value = "/detail/{deptId}")
    public R<SysDept> detail(@PathVariable Long deptId) {
        return R.ok(sysDeptService.detail(deptId));
    }

    /**
     * 根据地区编码查询机构详情
     *
     * @param dto 查询条件
     * @return R
     */
    @Inner
    @Operation(summary = "根据地区编码查询机构详情", description = "根据地区编码查询机构详情")
    @PostMapping("/detail/by/code")
    public R<SysDept> geDetailByOrgCode(@Valid @RequestBody AreaDepartQueryDTO dto) {
        return R.ok(sysDeptService.getDetailByOrgCode(dto));
    }

    /**
     * 导出部门
     *
     * @return List<DeptExcelVO>
     */
    @ResponseExcel
    @GetMapping("/export")
    public List<DeptExcelVO> export() {
        return sysDeptService.listExcelVo();
    }

    /**
     * 导入部门
     */
    @PostMapping("import")
    public R<?> importDept(@RequestExcel List<DeptExcelVO> excelVOList, BindingResult bindingResult) {
        return sysDeptService.importDept(excelVOList, bindingResult);
    }

    /**
     * 查询全部部门包含用户
     *
     * @param parentDeptId 父部门ID
     * @param type         查询类型
     */
    @GetMapping("/org")
    public R<Map<String, Object>> listOrgTree(Long parentDeptId, String type) {
        return R.ok(sysDeptService.listOrgTree(parentDeptId, type));
    }

    /**
     * 模糊搜索用户
     *
     * @param username 用户名/拼音/首字母
     * @return 匹配到的用户
     */
    @GetMapping("/org/user/search")
    public R<List<OrgTreeVO>> getOrgTreeUser(@RequestParam String username) {
        return R.ok(sysDeptService.getOrgTreeUser(username));
    }


    @Inner
    @GetMapping("/queryDepts")
    @Operation(summary = "根据部门id查询部门信息", description = "根据部门id查询部门信息")
    public R<List<SysDept>> queryDepts(@RequestParam List<Long> ids) {
        return R.ok(sysDeptService.queryDepts(ids));
    }

}
